void Search()
{
  //从底部往上搜线
  int i,j,cnt=0;
  float miderror=0;
  int white_begin=0; //白色区域开始的横坐标
  int white_end=79;   //白色区域结束的横坐标
  static int Search_Middle=40,Search_halfwidth=30;
  unsigned char Search_getleft_flag=0,Search_getright_flag=0;
  uint8 *start;
  for(i=0;i<60;i++)  //清空数组  //LMR[0][i]表示第i行的左边线值，LMR[2][i]表示第i行的右边线值，LMR[1][i]表示第i行的中值
  { 
    LMR[0][i]=0;
    LMR[1][i]=0;
    LMR[2][i]=0;
    LMR[3][i]=0;
    getLeft_flag[i]=0;
    getRight_flag[i]=0;
  }
//# define WHITE  1
//# define BLACK  0
  for(i=59;i>0;i--) //从第59行开始搜线
  {
    
    start=&(img[i*80]);//行的初始地址
    white_begin=0;
    white_end=79;
//    if(i==59)
//    {
//       get_edge(i);
//    }
    if(i!=59&&((getLeft_flag[i+1]!=0)||(getRight_flag[i+1]!=0))) //上一行至少一边搜到边线了
    {
      if(getLeft_flag[i+1]!=0)//上次找到了左边
     {  
       for(j=LMR[0][i+1]-3;j<=(LMR[0][i+1]+3);j++)   //因为上次搜到边线了，故这一行的边线从上一行边线的附近搜  如果这样搜不到可能遇到十字全白或圆环的情况
       {
          if(j<=1) continue;
          if(j>40) break;
          if((*(start+j)==WHITE)&&(*(start+j+1)==WHITE)&&(*(start+j-1)==BLACK)&&(*(start+j-2)==BLACK)) //由黑变白
          { 
            white_begin=j; //找到一个跳变点就认为搜到线了
            Search_getleft_flag=1;//得到左边的标志位
            if(getRight_flag[i+1]==0)//如果上次没有找到右边
            {
              for(j=j+15;j<=77;j++)   //为什么从左边右边是个像素点处开始遍历？   什么情况下LMR[2][i]会是0 
              {
                 if(j<=40) continue;
                 if((*(start+j+1)==BLACK)&&(*(start+j+2)==BLACK)&&(*(start+j)==WHITE)&&(*(start+j-1)==WHITE)) //由白变黑
                 { 
                  white_end=j; //找到一个跳变点就认为受到线了
                  Search_getright_flag=1;
                  break;
                 }
              }
            }
            break; 
          }
        }
      }
    
      if(getRight_flag[i+1]!=0)//上次找到了右边
      {
        for(j=LMR[2][i+1]-3;j<=(LMR[2][i+1]+3);j++)   //因为上次搜到边线了，故这一行的边线从上一行边线的附近搜
       {
          if(j<40) continue;
          if(j>=78) break;
          if((*(start+j+1)==BLACK)&&(*(start+j+2)==BLACK)&&(*(start+j)==WHITE)&&(*(start+j-1)==WHITE)) //由白变黑
          { 
            white_end=j+1; //找到一个跳变点就认为受到线了
            Search_getright_flag=1;
            
            if(getLeft_flag[i+1]==0)//如果上次没有找到左边
            {
              for(j=j-15;j>=2;j--)
              {
                  if(j<=40) continue;
                   if((*(start+j-1)==BLACK)&&(*(start+j-2)==BLACK)&&(*(start+j)==WHITE)&&(*(start+j+1)==WHITE)) //由黑变白
                  { 
                     white_begin=j; //找到一个跳变点就认为受到线了
                     Search_getleft_flag=1;
                    break; 
                  }
               }
            }   
            break; 
          }
        }
      }
    }
    else if(i>20)           //上一行没有同时搜到边线且不是顶部的行（顶部的行容易出错，排掉）
    {
      for(j=40;j>=2;j--)  //从中间往两边搜线
      {    
        if((*(start+j-2)==BLACK)&&(*(start+j-1)==BLACK)&&(*(start+j)==WHITE)&&(*(start+j+1)==WHITE)&&(white_begin==0))
        {
          white_begin=j;  //由黑变白 
          //black_L=j;  //白变黑  //左边
          Search_getleft_flag = 1;
        }
        if((*(start+80-j+1)==BLACK)&&(*(start+80-j)==BLACK)&&(*(start+80-j-1)==WHITE)&&(*(start+80-j-2)==WHITE)&&(white_end==79))
        {
          white_end=80-j-1;    //由白变黑
          //black_R=80-j+1;  //白变黑 //右边
          Search_getright_flag = 1;
        }        
      }
    }
	
    // LMR[0][i] = white_begin;
	// LMR[2][i] = white_end;
	
    //返回算中线  
    if(Search_getleft_flag==0 && Search_getright_flag==0)
    {
		if(i<58)
			Search_Middle = 2*LMR[1][i+1]-LMR[1][i+2];
		else if(i==58)
			Search_Middle = LMR[1][i+1];
		else
			Search_Middle = 40;
        // LMR[2][i] = LMR[2][i+1];
        // LMR[0][i] = LMR[0][i+1];
        // Search_halfwidth = LMR[3][i+1];
    }
    else if(Search_getleft_flag==0 && Search_getright_flag==1)//无左有右
    {
		LMR[2][i] = white_end;
		if(abs(LMR[2][i]-LMR[2][i+1])>3)
		{
			if(i<58)
			{
				LMR[2][i] = 2*LMR[2][i+1]-LMR[2][i+2];
			}
			else if(i==58)
			{
				LMR[2][i] = LMR[2][i+1];
			}
			else
			{
				//也只能假定59行为真的了   估计这里可能存在潜在bug
			}
		}
        Search_Middle = LMR[2][i] - Search_halfwidth;
        LMR[0][i] = LMR[2][i] - Search_halfwidth*2;
    }
    else if(Search_getleft_flag==1 && Search_getright_flag==0)//找到左 无右
    {
		LMR[0][i] = white_begin;
		if(abs(LMR[0][i]-LMR[0][i+1])>3)
		{
			if(i<58)
			{
				LMR[0][i] = 2*LMR[0][i+1]-LMR[0][i+2];
			}
			else if(i==58)
			{
				LMR[0][i] = LMR[0][i+1];
			}
			else
			{
				//也只能假定59行为真的了   估计这里可能存在潜在bug
			}
		}
        Search_Middle = LMR[0][i] + Search_halfwidth;
        LMR[2][i] = LMR[0][i] + Search_halfwidth*2; 
    }
    else if(Search_getleft_flag==1 && Search_getright_flag==1)//双边 ok!
    {
		//if((white_end!=79)&&(white_begin!=0)&&(white_begin<white_end)&&(white_end-white_begin>10)&&(abs(white_begin-LMR[0][i+1])<=3)&&(abs(white_end-LMR[2][i+1])<=3))
		if((white_begin<white_end)&&(white_end-white_begin>10)&&(abs(white_begin-LMR[0][i+1])<=3)&&(abs(white_end-LMR[2][i+1])<=3))
	    {
			LMR[0][i]=white_begin;  //左边线
			LMR[2][i]=white_end;    //右边线
		}
		else 
	    {
		  if(i<58)
		  {
			LMR[0][i] = 2*LMR[0][i+1]-LMR[0][i+2];
			LMR[2][i] = 2*LMR[2][i+1]-LMR[2][i+2];
		  }
		  else if(i==58)
		  {
			LMR[0][i]=LMR[0][i+1];  //左边线
			LMR[2][i]=LMR[2][i+1];  //右边线
		  }
		  else
		  {
			LMR[0][i]=white_begin;  //左边线
			LMR[2][i]=white_end;    //右边线
		  }
		}
				
        //赛道宽度-----半宽限幅//
        Search_halfwidth=(int)((LMR[2][i] - LMR[0][i])/2.0) ;
        if(Search_halfwidth < 20)
          Search_halfwidth = 20;
        else if(Search_halfwidth > 30)
          Search_halfwidth = 30; 
		//中心线
        Search_Middle = (int)((LMR[2][i] + LMR[0][i])/2.0) ;
    }
    //limit   Middle   中心线
    if(Search_Middle<5)
        Search_Middle=5;
    else if(Search_Middle>75)
        Search_Middle=75;    
    
    LMR[1][i]=Search_Middle;   //中线位置
    LMR[3][i]=Search_halfwidth*2;//赛道宽度
    getLeft_flag[i] = Search_getleft_flag;
    getRight_flag[i] = Search_getright_flag;
     
        
    if(i>38&&i<43&&LMR[1][i]!=0)//33-38
    {
      cnt++;
      miderror+=(LMR[1][i]-40);
    }
  }
 
  if(cnt!=0) 
    Middle_Err=miderror*1.0/cnt*0.8+(LMR[1][45]-40)*0.2;
  Push_And_Pull(Previous_Error,10,Middle_Err);
}